<template>
  <div class="tabs-container" :class="containerClass" ref="containerRef">
    <button
      v-for="(tab, index) in items"
      :key="getTabName(tab, index)"
      :ref="(el) => setButtonRef(el, index)"
      :class="[
        'tab-item',
        { active: activeTab === getTabName(tab, index), disabled: tab.disabled },
      ]"
      :disabled="tab.disabled"
      @click="handleTabClick(getTabName(tab, index))"
    >
      <span class="tab-label">{{ tab.label || "" }}</span>
    </button>
    <!-- 滑动下划线指示器（仅 underline 变体） -->
    <span
      v-if="variant === 'underline'"
      class="tab-indicator"
      :style="indicatorStyle"
    ></span>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, ref, watch, type ComponentPublicInstance } from "vue";
import type { TabItem } from "./types";

defineOptions({
  name: "Tabs",
});

const props = withDefaults(
  defineProps<{
    items: TabItem[];
    activeTab?: string | number;
    variant?: "default" | "underline" | "pills"; // 样式变体
    align?: "left" | "center" | "right"; // 对齐方式
    size?: "small" | "medium" | "large"; // 尺寸
  }>(),
  {
    variant: "underline",
    align: "left",
    size: "medium",
  }
);

const emit = defineEmits<{
  (e: "tab-change", name: string | number): void;
  (e: "update:activeTab", name: string | number): void;
}>();

// 获取标签页名称（name 或索引）
const getTabName = (tab: TabItem, index: number): string | number => {
  return tab.name !== undefined ? tab.name : index;
};

// 当前激活的标签页
const activeTab = ref(
  props.activeTab !== undefined
    ? props.activeTab
    : props.items.length > 0
      ? getTabName(props.items[0], 0)
      : 0
);

// 容器和按钮引用
const containerRef = ref<HTMLElement | null>(null);
const buttonRefs = ref<(HTMLElement | null)[]>([]);

const setButtonRef = (el: Element | ComponentPublicInstance | null, index: number) => {
  if (el && el instanceof HTMLElement) {
    buttonRefs.value[index] = el;
  }
};

// 下划线指示器样式
const indicatorStyle = ref({
  left: "0px",
  width: "0px",
});

// 更新下划线位置
const updateIndicator = () => {
  if (props.variant !== "underline" || !containerRef.value) {
    return;
  }

  nextTick(() => {
    const activeIndex = props.items.findIndex(
      (t, idx) => getTabName(t, idx) === activeTab.value
    );

    if (activeIndex < 0 || !buttonRefs.value[activeIndex]) {
      return;
    }

    const activeButton = buttonRefs.value[activeIndex] as HTMLElement;
    const container = containerRef.value;
    
    if (!container) return;
    
    const containerRect = container.getBoundingClientRect();
    const buttonRect = activeButton.getBoundingClientRect();

    const left = buttonRect.left - containerRect.left;
    const width = buttonRect.width;

    indicatorStyle.value = {
      left: `${left}px`,
      width: `${width}px`,
    };
  });
};

// 容器类名
const containerClass = computed(() => {
  return {
    [`tabs-${props.variant}`]: true,
    [`tabs-align-${props.align}`]: true,
    [`tabs-size-${props.size}`]: true,
  };
});

// 处理标签页点击
const handleTabClick = (name: string | number) => {
  // 找到对应的 tab
  const tabIndex = props.items.findIndex((t, idx) => getTabName(t, idx) === name);
  const tab = tabIndex >= 0 ? props.items[tabIndex] : null;
  
  if (tab?.disabled) return;

  activeTab.value = name;
  emit("tab-change", name);
  emit("update:activeTab", name);
  updateIndicator();
};

// 监听 props.activeTab 变化
watch(
  () => props.activeTab,
  (newTab) => {
    if (newTab !== undefined && newTab !== activeTab.value) {
      activeTab.value = newTab;
      updateIndicator();
    }
  }
);

// 监听 activeTab 内部变化
watch(activeTab, () => {
  updateIndicator();
});

// 监听窗口大小变化
const handleResize = () => {
  updateIndicator();
};

onMounted(() => {
  updateIndicator();
  window.addEventListener("resize", handleResize);
});

onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
});
</script>

<style scoped>
.tabs-container {
  display: flex;
  align-items: flex-end;
  gap: 0;
  border-bottom: var(--tabs-container-border-bottom-width, 1px) solid var(--tabs-container-border-color);
  background: var(--tabs-container-background);
  padding: var(--tabs-container-padding);
}

/* 默认样式 - underline 变体 */
.tabs-underline {
  border-bottom: var(--tabs-container-border-bottom-width, 1px) solid var(--tabs-container-border-color);
  position: relative;
}

.tabs-underline .tab-item {
  padding: var(--tabs-underline-item-padding);
  border: none;
  border-bottom: var(--tabs-item-border-bottom-width, 2px) solid transparent;
  background: var(--tabs-item-background);
  color: var(--tabs-item-color);
  font-size: var(--tabs-item-font-size);
  font-weight: var(--tabs-item-font-weight);
  cursor: pointer;
  transition: var(--tabs-item-transition);
  white-space: nowrap;
  position: relative;
  margin-bottom: var(--tabs-underline-item-margin-bottom, -1px);
}

.tabs-underline .tab-item:hover:not(.disabled) {
  color: var(--tabs-item-color-hover);
}

.tabs-underline .tab-item.active {
  color: var(--tabs-item-color-active);
  font-weight: var(--tabs-item-font-weight-active);
}

/* 滑动下划线指示器 */
.tab-indicator {
  position: absolute;
  bottom: 0;
  height: var(--tabs-item-border-bottom-width, 2px);
  background: var(--tabs-item-border-bottom-color-active);
  transition: left 0.3s ease, width 0.3s ease;
  pointer-events: none;
}

.tabs-underline .tab-item.disabled {
  opacity: var(--tabs-item-disabled-opacity);
  color: var(--tabs-item-color-disabled);
  cursor: not-allowed;
}

/* pills 变体 */
.tabs-pills {
  border-bottom: none;
  gap: var(--tabs-pills-gap);
}

.tabs-pills .tab-item {
  padding: var(--tabs-pills-item-padding);
  border: none;
  border-radius: var(--tabs-pills-item-border-radius);
  background: var(--tabs-item-background);
  color: var(--tabs-item-color);
  font-size: var(--tabs-item-font-size);
  font-weight: var(--tabs-item-font-weight);
  cursor: pointer;
  transition: var(--tabs-item-transition);
  white-space: nowrap;
  margin-bottom: 0;
}

.tabs-pills .tab-item:hover:not(.disabled) {
  background: var(--tabs-pills-item-background-hover);
}

.tabs-pills .tab-item.active {
  background: var(--tabs-pills-item-background-active);
  color: var(--tabs-pills-item-color-active);
  font-weight: var(--tabs-item-font-weight-active);
}

.tabs-pills .tab-item.disabled {
  opacity: var(--tabs-item-disabled-opacity);
  color: var(--tabs-item-color-disabled);
  cursor: not-allowed;
}

/* 对齐方式 */
.tabs-align-center {
  justify-content: center;
}

.tabs-align-right {
  justify-content: flex-end;
}

/* 尺寸 - underline */
.tabs-size-small.tabs-underline .tab-item {
  padding: var(--tabs-underline-item-padding-small);
  font-size: var(--tabs-item-font-size-small);
}

.tabs-size-large.tabs-underline .tab-item {
  padding: var(--tabs-underline-item-padding-large);
  font-size: var(--tabs-item-font-size-large);
}

/* 尺寸 - pills */
.tabs-size-small.tabs-pills .tab-item {
  padding: var(--tabs-pills-item-padding-small);
  font-size: var(--tabs-item-font-size-small);
}

.tabs-size-large.tabs-pills .tab-item {
  padding: var(--tabs-pills-item-padding-large);
  font-size: var(--tabs-item-font-size-large);
}

.tab-label {
  display: inline-block;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .tabs-container {
    padding: var(--tabs-container-padding-md);
  }

  .tabs-underline .tab-item {
    padding: var(--tabs-underline-item-padding-md);
    font-size: var(--tabs-item-font-size-small);
  }
}

@media (max-width: 768px) {
  .tabs-container {
    padding: var(--tabs-container-padding-sm);
  }

  .tabs-underline .tab-item {
    padding: var(--tabs-underline-item-padding-sm);
    font-size: var(--tabs-item-font-size-small);
  }
}
</style>